﻿namespace DimensionsHelper.Common.Metadata.Script;

/// <summary>
///     表达式Null值
/// </summary>
public class ExpressionNull() : ExpressionBasicType(BasicTypes.Null)
{
    public override bool CanImplicitlyConvert(BasicTypes type)
    {
        // Null 默认不能隐式转换成任何类型，其计算使用的类型应当由另一方决定。
        return false;
    }

    public override object GetValue(BasicTypes type)
    {
        switch (type)
        {
            case BasicTypes.Integer:
                return 0;
            case BasicTypes.Double:
                return (double)0;
            case BasicTypes.String:
                return "";
            case BasicTypes.Boolean:
                return false;
            case BasicTypes.Categorical:
                return new Categorical();
            default:
                throw ThrowHelper.TypeConvertFailed("Null", type.ToString());
        }
    }

    public override ExpressionBasicType ConvertTo(BasicTypes type)
    {
        switch (type)
        {
            case BasicTypes.Integer:
                return new ExpressionInteger(0);
            case BasicTypes.Double:
                return new ExpressionDouble(0);
            case BasicTypes.String:
                return new ExpressionString("");
            case BasicTypes.Boolean:
                return new ExpressionBoolean(false);
            case BasicTypes.Categorical:
                return new Categorical();
            default:
                throw ThrowHelper.TypeConvertFailed("Null", type.ToString());
        }
    }

    public override ExpressionBasicType Add(ExpressionBasicType expression)
    {
        return expression;
    }

    public override ExpressionBasicType Divide(ExpressionBasicType expression)
    {
        return new ExpressionInteger(0);
    }

    public override ExpressionBasicType Modulo(ExpressionBasicType expression)
    {
        throw ThrowHelper.ZeroCannotBeDivisor();
    }

    public override ExpressionBasicType Multiply(ExpressionBasicType expression)
    {
        if (expression.CanImplicitlyConvert(BasicTypes.Categorical))
        {
            return new Categorical();
        }

        if (expression.CanImplicitlyConvert(BasicTypes.Double) ||
            expression.CanImplicitlyConvert(BasicTypes.Integer) ||
            expression.CanImplicitlyConvert(BasicTypes.Boolean) ||
            expression.CanImplicitlyConvert(BasicTypes.Null))
        {
            return new ExpressionInteger(0);
        }

        throw ThrowHelper.TypeConvertFailed((string)expression.GetValue(BasicTypes.String), "Double");
    }

    public override ExpressionBasicType Subtract(ExpressionBasicType expression)
    {
        return ExpressionInteger.CreateExpressionNumber(Calculate(expression, CalculateTypes.Subtract));
    }

    public override string ToString()
    {
        return "Null";
    }
}